<template>
  <div>
    <InputModel
      @click="open"
      :value="processInfo.nameRule"
      :placeholder="t('请选择流程命名规则')"
    />
    <ModalPanel
      :visible="nameRule.visible"
      :width="1100"
      :title="t('流程命名规则')"
      @submit="submit"
      @close="close"
    >
      <template #left>
        <div class="title">
          <NodeHead :node-name="t('流程变量列表')" />
        </div>
        <a-tree
          style="height: 460px; overflow: auto"
          autoExpandParent
          defaultExpandAll
          :tree-data="nameRule.treeData"
          @select="selectNodes"
        />
      </template>
      <div class="title">
        <NodeHead :node-name="t('命名规则配置面板')" />
      </div>
      <div class="opr-box" :key="nameRule.renderKey">
        <a-button @click="addRandomNumber('-')">-</a-button>
        <a-select
          v-model:value="nameRule.serialRuleValue"
          :placeholder="t('点击选择流水号')"
          style="width: 240px; margin: 0 4px"
          :disabled="nameRule.canAddSerialRule ? false : true"
          @change="changeSerialRuleValue"
        >
          <a-select-option
            v-for="item in serialRuleList"
            :title="item.title"
            :key="item.key"
            :value="item.key"
          >
            {{ item.title }}
          </a-select-option>
        </a-select>
        <a-select
          v-model:value="nameRule.randomNumber"
          :placeholder="t('点击选择随机数')"
          style="width: 180px"
          @change="changeRandomNumber"
        >
          <a-select-option
            v-for="item in randomNumberRuleList"
            :key="item.key"
            :value="item.key"
            :title="item.title"
          >
            {{ item.title }}
          </a-select-option>
        </a-select>
        <div class="input-box">
          <span>{{ t('自定义文本：') }}</span>
          <a-input
            :placeholder="t('输入文本后点击确认')"
            v-model:value="nameRule.inputRandomNumber"
            :maxLength="20"
            class="input"
          />
          <a-button @click="addInputRandomNumber()" type="primary" class="button">{{
            t('确定')
          }}</a-button>
        </div>
      </div>
      <div class="panel">
        <div class="tag-box" v-if="nameRule.list.length > 0">
          <draggable v-model="nameRule.list" group="people" @end="end" item-key="key">
            <template #item="{ element, index }">
              <a-tooltip v-if="element.title.length > 30" :title="element.title">
                <a-tag closable @close="handleClose(index)">
                  {{ `${element.title.slice(0, 30)}...` }}
                </a-tag>
              </a-tooltip>
              <a-tag v-else closable @close="handleClose(index)">
                {{ element.title }}
              </a-tag>
            </template>
          </draggable>
        </div>
        <div v-else class="rule-tip-box">
          <EmptyBox
            :msg="
              t(
                '请先添加变量或自定义文本 格式举例：模板名称-发起人所属组织架构-发起人名称-yyyy-MM-dd-6位流水号  生成名称为：出差申请单-产品部-张三-20221011-000001',
              )
            "
          />
        </div>
      </div>
    </ModalPanel>
  </div>
</template>

<script setup lang="ts">
  import { reactive } from 'vue';
  import { storeToRefs } from 'pinia';
  import type { TreeProps } from 'ant-design-vue';
  import Draggable from 'vuedraggable';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import {
    ProcessNamedVariable,
    serialRuleList,
    randomNumberRuleList,
    symbolRuleMap,
  } from '/@bpmn/config/rules';
  import { NameRule } from '/@/model/workflow/workflowConfig';
  import { ModalPanel, EmptyBox } from '/@/components/ModalPanel/index';
  import InputModel from '/@bpmn/components/InputModel.vue';
  import { cloneDeep } from 'lodash-es';
  import { useBpmnStore } from '/@bpmn/store/bpmn';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  const store = useBpmnStore();
  const { processInfo } = storeToRefs(store);
  const nameRule: {
    visible: boolean;
    treeData: TreeProps['treeData'];
    list: NameRule;
    inputRandomNumber: string;
    serialRuleValue: string | undefined;
    randomNumber: string | undefined;
    canAddSerialRule: boolean;
    renderKey: number;
  } = reactive({
    visible: false,
    treeData: ProcessNamedVariable,
    list: [],
    inputRandomNumber: '',
    serialRuleValue: undefined,
    randomNumber: undefined,
    canAddSerialRule: true,
    renderKey: 0,
  });
  function submit() {
    let modelValue = '';
    if (nameRule.list.length > 0) {
      modelValue = nameRule.list.map((ele) => ele.title).join(' ');
    }
    processInfo.value.nameRuleConfigs = nameRule.list;
    processInfo.value.nameRule = modelValue;
    close();
  }
  function open() {
    if (processInfo.value.nameRuleConfigs)
      nameRule.list = cloneDeep(processInfo.value.nameRuleConfigs);
    nameRule.canAddSerialRule = true;
    let hasAddSerialRule =
      nameRule.list.length > 0
        ? nameRule.list.filter((ele) => {
            return ele.key.includes('serial_random');
          })
        : [];
    if (hasAddSerialRule.length > 0) {
      nameRule.canAddSerialRule = false;
    }
    nameRule.visible = true;
  }
  function close() {
    nameRule.list = [];
    nameRule.canAddSerialRule = true;
    nameRule.visible = false;
  }

  function selectNodes(_selectedKeys, e: { selectedNodes }) {
    if (e.selectedNodes.length > 0) {
      nameRule.list.push(...e.selectedNodes);
    }
  }
  function end(e) {
    let oldJson = nameRule.list[e.oldDraggableIndex];
    let newJson = nameRule.list[e.newDraggableIndex];
    nameRule.list[e.oldDraggableIndex] = newJson;
    nameRule.list[e.newDraggableIndex] = oldJson;
  }
  function handleClose(index: number) {
    if (nameRule.list.length > 0) {
      nameRule.list.splice(index, 1);
    }
    let arr = nameRule.list.filter((o) => {
      return o.key.includes('serial_number');
    });
    nameRule.canAddSerialRule = arr.length > 0 ? false : true;
  }
  function changeSerialRuleValue(_value, item) {
    if (nameRule.canAddSerialRule) {
      nameRule.canAddSerialRule = false;
      nameRule.list.push({ title: item.title, key: item.key });
      nameRule.renderKey++;
    }
    nameRule.serialRuleValue = undefined;
  }
  function changeRandomNumber(_value, item) {
    nameRule.list.push({ title: item.title, key: item.key });
    nameRule.randomNumber = undefined;
    nameRule.renderKey++;
  }
  function addRandomNumber(str: string) {
    let item = symbolRuleMap.has(str) ? symbolRuleMap.get(str) : null;
    if (item) nameRule.list.push(item);
  }
  function addInputRandomNumber() {
    if (nameRule.inputRandomNumber) {
      nameRule.list.push({
        key: '#{' + nameRule.inputRandomNumber + '}#',
        title: nameRule.inputRandomNumber,
      });
      nameRule.inputRandomNumber = '';
    }
  }
</script>

<style lang="less" scoped>
  .title {
    display: flex;
    justify-content: space-between;
    height: 40px;
    font-size: 16px;
    color: #333;
    border-bottom: 1px solid #f0f0f0;
    padding: 0;
    margin: 0;
  }

  .opr-box {
    height: 50px;
    border-bottom: 1px solid #f0f0f0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;

    .input-box {
      .input {
        width: 180px;
        font: 12px;
        margin-right: 4px;
      }

      .button {
        font-size: 12px;
      }
    }
  }

  .rule-tip-box {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    flex-direction: column;

    .tip-title {
      font-size: 48px;
    }

    .tip-content {
      font-size: 14px;
      color: #9e9d9d;
      padding: 10px 40px;
    }
  }

  .tag-box {
    padding: 10px;
  }

  :deep(.ant-tag) {
    margin: 4px;
    padding: 4px;
    border: none;
    background-color: #eef4ff;
    color: #676767;
    font-size: 14px;
  }

  :deep(.ant-tag-close-icon) {
    margin-left: 10px;
    font-size: 14px;
  }

  .panel {
    border: 1px solid #f0f0f0;
    height: 400px;
    overflow: auto;
  }
</style>
